package org.su.generalmvc.jdbc;

import org.su.generalmvc.jdbc.dao.Dao;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

public class DaoFactory {
	/**
	 * strDefaultFile 默认配置文件名称
	 */
	public static final String DEFAULT_FILE = "jdbc";

	// 主数据库
	private static DataSource masterDataSource = null;

	// 外部数据库
	private static DataSource slaveDataSource = null;

	private static Map<String, DataSource> dataSourceMap = new HashMap<String, DataSource>();

	private static ThreadLocal<IDao> threadDao = new ThreadLocal<IDao>();
	
	protected static final Log logger = LogFactory.getLog(DaoFactory.class);

	/**
	 * 防止重复加载
	 */
	private static boolean isLoaded = false;

	/**
	 * 创建DAO
	 * 
	 * @param transactionLevel
	 *            事务级别
	 * @return
	 * @throws java.sql.SQLException
	 */
	public static IDao createDao(int transactionLevel) {
		IDao result = threadDao.get();

		if (result == null) {
			try {
				result = Dao.createDao(transactionLevel);
			} catch (Exception e) {
				throw new RuntimeException("Max:" + getNumActive(), e);
			}
			threadDao.set(result);

		} else {
			result.addRefCount();
			if (transactionLevel != 0) {
				result.startTrans(transactionLevel);
			}
		}
		return result;
	}

	public static boolean destroyDao(IDao dao) {
		IDao result = threadDao.get();
		if (result == dao) {
			threadDao.set(null);
			return true;
		}

		return false;
	}

	public static boolean forceCloseDao(IDao dao) {
		boolean result = false;
		try {
			if (dao != null) {
				dao.forceClose();
			}
		} finally {
			result = forceCloseDao();
		}

		return result;
	}

	public static boolean forceCloseDao() {
		IDao result = threadDao.get();
		if (result != null) {
			result.forceClose();
			return true;
		}

		return false;
	}

	public static IDao createDao() {
		return createDao(0);
	}

	public static IDao createSlaveDao() {
		return new Dao(slaveDataSource);
	}

	public static IDao createDao(String poolName) {
		DataSource ds = dataSourceMap.get(poolName);
		if (ds != null) {
			return new Dao(ds);
		}

		return null;
	}

	public static Connection getMasterConnection() throws SQLException {
		return masterDataSource.getConnection();
	}

	/**
	 * 获取主连接池的连接数
	 * 
	 * @return
	 * @throws java.sql.SQLException
	 */
	public static int getNumActive() {
		/*if (masterDataSource instanceof BasicDataSource) {
			return ((BasicDataSource) masterDataSource).getNumActive();
		}*/

		return -1;
	}

	/**
	 * 根据 jdbc.properties 初始化配置文件
	 * 
	 * @throws javax.naming.NamingException
	 */
	public static void init() throws NamingException {

		if (!isLoaded) {
			isLoaded = true;
			ResourceBundle resources = ResourceBundle.getBundle(DEFAULT_FILE);
			InitialContext mycontext = new InitialContext();

			Enumeration<String> keys = resources.getKeys();
			Enumeration<String> key2s = resources.getKeys();
			String serverType = "tomcat";
			while (key2s.hasMoreElements()) {
				String key = key2s.nextElement();
				if(key.endsWith("serverType")){
					serverType = resources.getString(key);
				}
			}
			
			while (keys.hasMoreElements()) {
				String key = keys.nextElement();
				if (key.endsWith("PoolName")) {
					String poolName = resources.getString(key);
					if (StringUtils.isNotBlank(poolName)) {
						DataSource dataSource = null;
						if(serverType.equals("weblogic")){
							logger.debug("weblogic db lookup。。。。。。。。。。。。。。。。。。。。.");
							dataSource = (DataSource) mycontext
								.lookup(poolName);
						}else{
							logger.debug("tomcat db lookup。。。。。。。。。。。。。。。。。。。。.");
							dataSource = (DataSource) mycontext
									.lookup("java:/comp/env/" + poolName);
						}
						dataSourceMap.put(key, dataSource);
						

						if ("masterPoolName".equals(key)) {
							if (masterDataSource == null) {
								masterDataSource = dataSource;
							}
						} else if ("DBPoolName".equals(key)) {
							if (masterDataSource == null) {
								masterDataSource = dataSource;
							}
						} else if ("slavePoolName".equals(key)) {
							slaveDataSource = dataSource;
						}
					}
				}
			}
		}
	}
}
